
#include <stdio.h>

#include "land_base.h"

#include "land_graphics.h"
#include "land_math.h"
#include "land_ogl.h"
#include "land_2d.h"


static LandWindow* window;
static LandCanvas* canvas;
int close = 0;
float angle = 0.f;

LandVector red = { 1.f, 0.f, 0.f, 1.f };
LandVector blue = { 0.f, 0.f, 1.f, 1.f };
LandVector green = { 0.f, 1.f, 0.f, 1.f };
LandVector white = { 1.f, 1.f, 1.f, 1.f };


LandFont* font;
LandScene* scene;
LandObj* root;
LandLabel* label;
unsigned fsize = 16;
LandFloat fwidth = 100.f;
LandFrame* frame;
LandSprite* sprite;
unsigned findex = 0;

typedef struct  {
    LandButton btn;
    LandShape* shape;
}ShapeButton;

static void
onBtnStatus(LandButton* btn, LandObjEvent* evt) {
    LandVector* color = &blue;
    switch (btn->status) {
    case LAND_BUTTON_STATUS_UP:
        color = &blue;
        break;
    case LAND_BUTTON_STATUS_HOVER:
        color = &green;
        break;
    case LAND_BUTTON_STATUS_DOWN:
        color = &red;
        break;
    }
    LandVector rect = { 0.f, 0.f, 40.f, 40.f };
    ShapeButton* sbtn = (ShapeButton*)btn;
    landClearShape(sbtn->shape);
    landShapeRect(sbtn->shape, &rect, color);
}

static void
onBtnClick(LandButton* btn, LandObjEvent* evt) {
    landSpriteIndex(sprite, findex ++);
    if (findex > 3) {
        findex = 0;
    }
}

static void
freeButton(LandRef* ref) {
    ShapeButton* btn = (ShapeButton*)ref;
    landReleaseRef(btn->shape);
}

static ShapeButton*
createButton() {
    ShapeButton* btn = (ShapeButton*)
        landNewExtendButton(sizeof(ShapeButton), freeButton);
    btn->btn.onStatus = onBtnStatus;
    btn->btn.onClick = onBtnClick;
    btn->shape = landNewShape();
    landAddObjChild(btn, btn->shape);

    LandVector rect = { 0.f, 0.f, 40.f, 40.f };
    LandVector2D size = { 40.f, 40.f, 1.f };

    landObjColor(btn->shape, blue);
    landShapeRect(btn->shape, &rect, &blue);
    landObjSize(btn, 40.f, 40.f);
    return btn;
}

static void
onWindowEvt(LandWindow* window, LandWindowEvent* evt) {
    switch (evt->type) {
    case LAND_WINDOW_EVENT_CLOSE:
        close = 1;
        break;
    }
    LandObjEvent objEvt = { 0 };
    objEvt.type = LAND_OBJ_WINDOW_EVENT;
    objEvt.ud = evt;
    landObjEvent(root, &objEvt);
}

static void
loadFrame() {
    const char* path = "F:\\project\\RPGInPaper\\art\\role\\texture.png";
    
    LandTexture* tex = landNewPngTexture(path);
    landTextureFilter(tex,
        LAND_TEXTURE_FILTER_NEAREST, LAND_TEXTURE_FILTER_NEAREST);
    frame = landNewFrame(tex, 32);
    landRetainRef(frame);

    for (unsigned i = 0; i < 4; i++) {
        LandVector rect = { 0.f, 32.f * i, 32.f, 32.f };
        LandVector border = { 0.f, 0.f, 0.f, 0.f };
        landRegFrameSlot(frame, 32.f, 32.f, &rect, &border);
    }
}

int main(){

    LandBase baseConfig = { 0 };
    landDefaultBase(&baseConfig);
    landInitBase(&baseConfig);
    landStartBase();

    LandOgl oglConfig = { 0 };
    LandBackend* backend = landInitOgl(&oglConfig);
    LandGraphics lgConfig = { 0 };
    landInitGraphics(&lgConfig, backend);
    landInit2D();

    unsigned winRect[] = {0, 0, 400, 400};
    window = landOpenWindow("", winRect);
    window->onEvent = onWindowEvt;

    
    const char* mousePath = "C:\\Users\\dd\\Desktop\\mouse.png";
    LandTexture* texture = landNewPngTexture(mousePath);
    landRetainRef(texture);
    //msyh.ttc
    font = landNewFont("c:\\Windows\\Fonts\\msyh.ttc");
    landRetainRef(font);

    loadFrame();

    scene = landNewScene(400, 400);
    landRetainRef(scene);
    root = landNewObj();
    landRetainRef(root);
    //LandShape* shape = landNewShape();
    //landAddObjChild(root, shape);
    //LandVector shapeRect = { 20.f, 20.f, 200.f, 200.f };
    //landShapeRect(shape, &shapeRect, &green);
    //shapeRect.left = 80.f; shapeRect.right = 280.f;
    //landShapeRect(shape, &shapeRect, &red);


    //L2DText* text = landNewText(font);
    //landAddObjChild(root, text);
    //landTextStr(text, ts, (unsigned)strlen(ts));
    //landObjPosition(text, 0.f, 10.f);
    //landObjColor(text, &red);

    LandImage* image = landNewImage(texture);
    landAddObjChild(root, image);
    LandVector2D imgPos = { 200.f, 100.f, 1.f };
    landObjPosition(image, 200.f, 200.f);

    LandImage* fontImage = landNewImage(landGetFontTexture(font));
    landAddObjChild(root, fontImage);
    //landObjSize(fontImage, 1024.f, 1024.f);


    const unsigned char* ts = "lgx gx解释得乱七八糟的的，！@#￥%……&";
    label = landNewLabel(font, 16);
    landAddObjChild(root, label);
    landLabelStr(label, ts, (unsigned)strlen(ts));
    landObjPosition(label, 100.f, 100.f);
    landObjColor(label, red);
    landObjSize(label, 200.f, 200.f);
    //landObjRotate(label, 1.f);

    sprite = landNewSprite(frame);
    landAddObjChild(root, sprite);
    landSpriteIndex(sprite, 1);
    landObjScale(sprite, 2.f, 2.f);
    landObjAnchor(sprite, 0.5f, 0.5f);
    landObjPosition(sprite, 100, 200.f);
    //landObjRotate(sprite, 0.5f);


    LandSprite* sprite2 = landNewSprite(frame);
    landAddObjChild(sprite, sprite2);
    landObjPosition(sprite2, 20, 20.f);
    //landObjScale(sprite2, 4.f, 4.f);
    landObjAnchor(sprite2, 0.5f, 0.5f);

    ShapeButton* btn = createButton();
    landAddObjChild(root, btn);
    landObjPosition(btn, 300.f, 300.f);
    landObjRotate(btn, 1.f);

    LandVector2D local = { 0.f, 0.f, 1.f };
    LandVector2D world = { 200.f, 100.f, 1.f };


    float angle = 0.f;
    unsigned counter = 0;

    uint64_t lt = landTime();
    uint64_t nt = 0;
    int64_t dt = 0;

    uint64_t ft = lt;
    int frame = 0;
    
    while (!close) {
        nt = landTime();
        dt = (nt - lt);
        if (dt < 14) {
            landSleep(2);
            continue;
        }
        else if(dt < 17) {
            landSleep(1);
            continue;
        }
        else if(dt <= 32){
            lt = nt - (dt - 17);
        }
        else if(dt > 32){
            lt = nt;
        }

        frame++;
        angle += 0.02f;
        if ((nt - ft) >= 140) {
            //printf("frame:%d\n", frame);
            char buf[512];
            sprintf(buf, "中国智造\n当前Fps:(%d)\n"
                "rand[%d]\n"
                "draw:%d", frame, rand(), landCountDraw());
            landLabelStr(label, buf, strlen(buf));
            frame = 0;
            ft = nt;
            landSpriteIndex(sprite, findex++);
            if (findex > 3) {
                findex = 0;
            }
        }
        landBeginDraw();

        //findex++;
        //if (findex >= 8) {
        //    findex = 0;
        //}

        unsigned width = window->width;
        unsigned height = window->height;
        //printf("mouse:%f  %f\n", mouseX, mouseY);
        //landObjPosition(sprite, 100, 200.f);

        landSceneSize(scene, width, height);
        landDrawScene(scene, root);

        //lgCanvasSize(canvas, width, height);
        //lgClearCanvas(canvas);
        //LGDraw draw = { 0 };
        //draw.count = 6;
        //draw.shader = shader;
        //draw.vertex = vertex;
        //draw.drawType = LG_DRAW_TRIANGLES;
        //lgRegUniformCanvas(&draw, "lgBaseTexture", scene->canvas);
        //lgDraw(canvas, &draw);
        //lgFlushCanvas(canvas);

        landRenderWindow(window, scene->canvas);

        landDispatchGraphics();
        landAutoGcRef();
    }
    return 0;
}